#include "app_ringbuff.h"
#include "app_params.h"
#include "bsp_uart.h"
#include "app_comm.h"

volatile bleAdvDataQueue_t bleAdvDataQueue = {
    .ReadIdx = 0,
    .WriteIdx = 0,
    .ToRead = 0,
    .Lock = 0,
};

void bleAdvDataQueueInit(void)
{
    bleAdvDataQueue.ReadIdx = 0;
    bleAdvDataQueue.WriteIdx = 0;
    bleAdvDataQueue.ToRead = 0;
}

int bleAdvDataSave(uint8_t *pMac, uint8_t *pData, uint8_t len)
{
    int status = 0;

    if(NULL == pMac)
    {
        return 1;
    }
    if(NULL == pData)
    {
        return 2;
    }
    if(0 == len)
    {
        return 3;
    }
    if(0 != bleAdvDataQueue.Lock)
    {
        return 5;
    }
    bleAdvDataQueue.Lock = 1;

    // vPortEnterCritical();
    memcpy((uint8_t *)bleAdvDataQueue.advData[bleAdvDataQueue.WriteIdx].mac, pMac, 6);
    memcpy((uint8_t *)bleAdvDataQueue.advData[bleAdvDataQueue.WriteIdx].data, pData, len);
    bleAdvDataQueue.advData[bleAdvDataQueue.WriteIdx].len = len;

    if(bleAdvDataQueue.ToRead >= ADV_DATA_QUEUE_LEN)
    {
        bleAdvDataQueue.WriteIdx ++;
        if (bleAdvDataQueue.WriteIdx >= ADV_DATA_QUEUE_LEN)
        {
            bleAdvDataQueue.WriteIdx = 0;
        }
        bleAdvDataQueue.ReadIdx = bleAdvDataQueue.WriteIdx;
    }
    else
    {
        bleAdvDataQueue.ToRead ++;
        bleAdvDataQueue.WriteIdx ++;
        if (bleAdvDataQueue.WriteIdx >= ADV_DATA_QUEUE_LEN)
        {
            bleAdvDataQueue.WriteIdx = 0;
        }
    }
    bleAdvDataQueue.Lock = 0;
    // vPortExitCritical();
    return status;
}




int bleAdvDataRead(uint8_t *pMac, uint8_t *pData, uint8_t *pLen)
{
    int status = 0;

    if(NULL == pMac)
    {
        return 1;
    }
    if(NULL == pData)
    {
        return 2;
    }
    if(NULL == pLen)
    {
        return 3;
    }

    if(0 == bleAdvDataQueue.ToRead)
    {
        return 4;
    }
    if(0 != bleAdvDataQueue.Lock)
    {
        return 5;
    }
    bleAdvDataQueue.Lock = 1;
    // vPortEnterCritical();
    *pLen = bleAdvDataQueue.advData[bleAdvDataQueue.ReadIdx].len;
    memcpy(pMac, (uint8_t *)bleAdvDataQueue.advData[bleAdvDataQueue.ReadIdx].mac, 6);
    memcpy(pData, (uint8_t *)bleAdvDataQueue.advData[bleAdvDataQueue.ReadIdx].data, bleAdvDataQueue.advData[bleAdvDataQueue.ReadIdx].len);

    bleAdvDataQueue.ToRead --;
    bleAdvDataQueue.ReadIdx ++;
    if (bleAdvDataQueue.ReadIdx >= (ADV_DATA_QUEUE_LEN))
    {
        bleAdvDataQueue.ReadIdx = 0;
    }
    // vPortExitCritical();
    bleAdvDataQueue.Lock = 0;
    return status;
}


int bleAdvDataHandle(uint8_t *pMac, uint8_t *pData, uint8_t len)
{
    advDataFrame_t *pAdvDataFrame = NULL;
    // if(0 == memcmp(pMac, globalVariable.devMac, 6))
    // {
        // esp_printf(" adv data len %dByte \r\n", len);
        // esp_arrprintf(" adv data ", pData, len);
    //     bleAdvDataSave(pMac, pData, len);
    // }


    if(31 != len)
    {
        return 1;
    }

    pAdvDataFrame = (advDataFrame_t *)&pData[3];

    if((0xFF != pAdvDataFrame->vendorCustomCode[1]) || (0x22 != pAdvDataFrame->vendorCustomCode[0]))
    {
        // esp_printf(" vendorCustomCode err... \r\n");
        return 2;
    }

    if (pAdvDataFrame->lrc != lrc_checksum(pAdvDataFrame->mac, 23))
    {
        // esp_printf(" lrc err... \r\n");
        return 3;
    }
    // if(0 != memcmp(pMac, globalVariable.devMac, 6))
    // {
    //     return 4;
    // }
    // esp_printf(" adv data len %dByte \r\n", len);
    // esp_arrprintf(" adv data ", pData, len);
    // esp_sprintf("... %d-%d-%d\r\n", bleAdvDataQueue.ToRead, bleAdvDataQueue.WriteIdx, bleAdvDataQueue.ReadIdx);
    bleAdvDataSave(pMac, pData, len);
    return 0;
}





int bleAdvDataSaveHandle(uint8_t *pMac, uint8_t *pData, uint8_t len, int rssi)
{
    advDataFrame_t *pAdvDataFrame = NULL;

    // esp_sprintf(".");
    if(31 != len)
    {
        return 1;
    }

    pAdvDataFrame = (advDataFrame_t *)&pData[3];

    if((0xFF != pAdvDataFrame->vendorCustomCode[1]) || (0x22 != pAdvDataFrame->vendorCustomCode[0]))
    {
        // esp_printf(" vendorCustomCode err... \r\n");
        return 2;
    }

    if (pAdvDataFrame->lrc != lrc_checksum(pAdvDataFrame->mac, 23))
    {
        // esp_printf(" lrc err... \r\n");
        return 3;
    }
    pData[0] = (uint8_t)rssi;
    bleAdvDataSave(pMac, pData, len);
    return 0;
}


